﻿using System;
using TweetSharp.Fluent;
using TweetSharp.Model;
using TweetSharp.Extensions;
using System.Linq;
using System.Collections.Generic;
using Halfwit.Pollers;
using System.Windows.Threading;
using System.Windows.Input;
using TweetSharp.Twitter.Fluent;
using TweetSharp.Twitter.Model;
using TweetSharp.Twitter.Extensions;
using System.Collections.ObjectModel;
using System.Windows;

namespace Halfwit.ViewModels
{
    public class SearchViewModel : TweetsViewModel
    {
        public SearchViewModel(MainViewModel host, string text)
            : base(host)
        {
            this.Title = "Tweets containing '" + text + "'";
            this.Uri = "http://twitter.com/search?q=" + System.Web.HttpUtility.UrlEncode(text);

            _text = text;

            Search = new RelayCommand("Search", PerformSearch, CanPerformSearch);
            SaveSearch = new RelayCommand("Save Search", SaveCurrentSearch, CanPerformSearch);
            DeleteSavedSearch = new RelayCommand("Delete Saved Search", DeleteSearch);

            Pollers.Add(new SearchPoller(() => Text, PollCompleted));

            TwitterConnection.CreateRequest().SavedSearches().List().CallbackTo(LoadSavedSearches).BeginRequest();
        }

        private string _text;
        private ObservableCollection<TwitterSavedSearch> _savedSearches = new ObservableCollection<TwitterSavedSearch>();

        private bool CanPerformSearch(object o)
        {
            return !String.IsNullOrEmpty(_text.Trim());
        }

        private void PerformSearch(object o)
        {
            Tweets.Clear();
            Pollers[0].Reset();
            Refresh.Execute(null);
        }

        private void SaveCurrentSearch(object o)
        {
            var result = TwitterConnection.CreateRequest().SavedSearches().Create(this.Text).Request();
            if (result.IsFailWhale || result.IsNetworkError || result.IsTwitterError)
            {
                var error = result.AsError();

                Status = error != null ? error.ErrorMessage
                    : !String.IsNullOrEmpty(result.ResponseHttpStatusDescription) ? result.ResponseHttpStatusDescription
                    : "Unknown error. Possible space-time continuum anomaly.";
                return;
            }

            var ss = result.AsSavedSearch();
            if (ss != null && !_savedSearches.Any(s => s.Query == ss.Query)) _savedSearches.Add(ss);

            Status = "Search saved.";
        }

        private void DeleteSearch(object o)
        {
            var ss = o as TwitterSavedSearch;
            if (ss == null) return;

            if (MessageBox.Show(String.Format("Delete saved search for '{0}'?", ss.Query), "Confirm Delete", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.No)
            {
                return;
            }

            var result = TwitterConnection.CreateRequest().SavedSearches().Delete(ss.Id).Request();
            if (result.IsFailWhale || result.IsNetworkError || result.IsTwitterError)
            {
                var error = result.AsError();

                Status = error != null ? error.ErrorMessage
                    : !String.IsNullOrEmpty(result.ResponseHttpStatusDescription) ? result.ResponseHttpStatusDescription
                    : "Unknown error. Possible space-time continuum anomaly.";
                return;
            }

            SavedSearches.Remove(ss);
            Status = "Saved search for '" + ss.Query + "' deleted.";
        }

        private void LoadSavedSearches(object sender, TwitterResult result, object userState)
        {
            if (App.Current.Dispatcher != Dispatcher.CurrentDispatcher)
            {
                App.Current.Dispatcher.Invoke(new Action<object, TwitterResult, object>(LoadSavedSearches), sender, result, null);
                return;
            }

            _savedSearches.Clear();

            if (result.IsFailWhale || result.IsNetworkError || result.IsTwitterError)
            {
                return;
            }

            var ss = result.AsSavedSearches();
            if (ss == null) return;

            foreach (var s in ss)
            {
                _savedSearches.Add(s);
            }
        }

        public ICommand Search { get; private set; }
        public ICommand SaveSearch { get; private set; }
        public ICommand DeleteSavedSearch { get; private set; }

        public string Text
        {
            get { return _text; }
            set
            {
                _text = value;
                Title = "Tweets containing '" + _text + "'";
                OnPropertyChanged("Text");
                OnPropertyChanged("Title");
            }
        }

        public IList<TwitterSavedSearch> SavedSearches
        {
            get { return _savedSearches; }
        }
    }
}
